﻿/*
 * Nix PBEM Game Engine.
 * Copyright (C) 2008, Lauris Bukšis-Haberkorns
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace Nix.PBeM.Engine.DataTypes
{
	/// <summary>
	/// Stance manager interface.
	/// </summary>
	public interface IStanceManager
	{
		/// <summary>
		/// Compares the specified stances.
		/// </summary>
		/// <param name="stance1">The stance1.</param>
		/// <param name="stance2">The stance2.</param>
		/// <returns></returns>
		int Compare (object stance1, object stance2);

		/// <summary>
		/// Finds the specified stance by tag.
		/// </summary>
		/// <param name="tag">The tag.</param>
		/// <returns></returns>
		object Find(string tag);

		/// <summary>
		/// Gets the name of the specified stance.
		/// </summary>
		/// <param name="stance">The stance.</param>
		/// <returns></returns>
		string GetName(object stance);

		/// <summary>
		/// Gets the name of the stance by tag.
		/// </summary>
		/// <param name="tag">The tag.</param>
		/// <returns></returns>
		string GetName(string tag);

		/// <summary>
		/// Gets the tag of the stance.
		/// </summary>
		/// <param name="stance">The stance.</param>
		/// <returns></returns>
		string GetTag(object stance);

		/// <summary>
		/// Gets the default stance.
		/// </summary>
		/// <value>The default stance.</value>
		object DefaultStance { get ; }

		/// <summary>
		/// Gets the minimal stance required to stack.
		/// </summary>
		/// <value>The minimal stack stance.</value>
		object MinimalStackStance { get; }
	}

	/// <summary>
	/// Default stance manager.
	/// </summary>
	public class StanceManager : IStanceManager
	{
		private Dictionary<string, Stance> stances = new Dictionary<string, Stance>();

		/// <summary>
		/// Initializes a new instance of the <see cref="StanceManager"/> class.
		/// </summary>
		public StanceManager()
		{
			this.stances.Add("enemy", Stance.Enemy);
			this.stances.Add("hostile", Stance.Hostile);
			this.stances.Add("neutral", Stance.Neutral);
			this.stances.Add("friendly", Stance.Friendly);
			this.stances.Add("ally", Stance.Ally);
		}

		/// <summary>
		/// Compares the specified stances.
		/// </summary>
		/// <param name="stance1">The stance1.</param>
		/// <param name="stance2">The stance2.</param>
		/// <returns></returns>
		public int Compare(object stance1, object stance2)
		{
			return ((Stance)stance1).CompareTo(stance2);
		}

		/// <summary>
		/// Finds the specified stance by tag.
		/// </summary>
		/// <param name="tag">The tag.</param>
		/// <returns></returns>
		public object Find(string tag)
		{
			if ( ! this.stances.ContainsKey(tag) )
				return Stance.Neutral;
			return this.stances[tag];
		}

		/// <summary>
		/// Gets the default stance.
		/// </summary>
		/// <value>The default stance.</value>
		public object DefaultStance
		{
			get
			{
				return Stance.Neutral;
			}
		}

		/// <summary>
		/// Gets the minimal stance required to stack.
		/// </summary>
		/// <value>The minimal stack stance.</value>
		public object MinimalStackStance
		{
			get
			{
				return Stance.Ally;
			}
		}

		/// <summary>
		/// Gets the tag of the stance.
		/// </summary>
		/// <param name="stance">The stance.</param>
		/// <returns></returns>
		public string GetTag ( object stance )
		{
			foreach(string tag in this.stances.Keys)
				if (this.stances[tag] == (Stance)stance)
					return tag;
			throw new EngineException("Unknown stance");			
		}

		/// <summary>
		/// Gets the name of the stance by tag.
		/// </summary>
		/// <param name="tag">The tag.</param>
		/// <returns></returns>
		public string GetName ( string tag )
		{
			return this.GetName(this.Find(tag));
		}

		/// <summary>
		/// Gets the name of the specified stance.
		/// </summary>
		/// <param name="stance">The stance.</param>
		/// <returns></returns>
		public string GetName( object stance )
		{
			switch((Stance)stance)
			{
				case Stance.Enemy:
					return "Enemy";
				case Stance.Hostile:
					return "Hostile";
				default:
				case Stance.Neutral:
					return "Neutral";
				case Stance.Friendly:
					return "Friendly";
				case Stance.Ally:
					return "Allied";
			}
		}
	}
}
